# SPDX-License-Identifier: Apache-2.0

include_guard(GLOBAL)

if(CONFIG_FRAME_WARN)
  common_cc_options(-Wframe-larger-than=${CONFIG_FRAME_WARN})
endif()

add_library(kernel_interface INTERFACE)
target_link_libraries(kernel_interface INTERFACE common_interface)

kernel_cc_options(-ffreestanding)

if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  execute_process(
    COMMAND which
    ${CMAKE_LINKER}
    OUTPUT_VARIABLE GCC_TOOLCHAIN_DIR
  )
  get_filename_component(GCC_TOOLCHAIN_DIR ${GCC_TOOLCHAIN_DIR} DIRECTORY)
  kernel_cc_options(--prefix=${GCC_TOOLCHAIN_DIR}/${CROSS_COMPILE})

  get_filename_component(SECOND_FOLDER ${GCC_TOOLCHAIN_DIR}/${CROSS_COMPILE} DIRECTORY)
  kernel_cc_options(--gcc-toolchain=${SECOND_FOLDER})

  kernel_cc_options(-no-integrated-as)

  kernel_cc_options(-Wno-unused-value)
  kernel_cc_options(-Wno-sign-compare)
  kernel_cc_options(-Wno-uninitialized)
endif()

kernel_cc_options(-fno-delete-null-pointer-checks)
kernel_cc_options(-Wno-frame-address)
kernel_cc_options(-Wno-format-overflow)
kernel_cc_options(-Wno-int-in-bool-context)

# Tell gcc to never replace conditional load with a non-conditional one
kernel_cc_options(--param=allow-store-data-races=0)

if(CONFIG_CC_HAS_STACKPROTECTOR_NONE)
  kernel_cc_options(-fno-stack-protector)
endif()
if(CONFIG_STACKPROTECTOR)
  kernel_cc_options(-fstack-protector)
endif()
if(CONFIG_STACKPROTECTOR_STRONG)
  kernel_cc_options(-fstack-protector-strong)
endif()

if(CONFIG_CC_IS_CLANG)
  kernel_cc_options(-Qunused-arguments)
  # CLANG uses a _MergedGlobals as optimization, but this breaks modpost, as the
  # source of a reference will be _MergedGlobals and not on of the whitelisted names.
  # See modpost pattern 2
  kernel_cc_options(-mno-global-merge)
  kernel_cc_options(-fcatch-undefined-behavior)

  # Issue all the warnings demanded by strict ISO C and ISO C++;
  # reject all programs that use forbidden extensions,
  # and some other programs that do not follow ISO C and ISO C++.
  # For ISO C, follows the version of the ISO C standard specified
  # by any -std option used.
  kernel_cc_options(-Wno-pedantic)

  kernel_cc_options(-Wno-gnu-statement-expression -Wno-cast-align)
endif()

if(CONFIG_FRAME_POINTER)
  kernel_cc_options(-fno-omit-frame-pointer -fno-optimize-sibling-calls)
else()
  kernel_cc_options(-fomit-frame-pointer)
endif()

kernel_cc_options(-fno-var-tracking-assignments)

if(CONFIG_DEBUG_SECTION_MISMATCH)
  kernel_cc_options(-fno-inline-functions-called-once)
endif()

if(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION)
  kernel_cc_options(-ffunction-sections -fdata-sections)
  target_ld_options(kernel_interface INTERFACE -Wl,--gc-sections)
endif()

# disable stringop warnings in gcc 8+
kernel_cc_options(-Wno-stringop-truncation)

# disable invalid "can't wrap" optimizations for signed / pointers
kernel_cc_options(-fno-strict-overflow)

# clang sets -fmerge-all-constants by default as optimization, but this
# is non-conforming behavior for C and in fact breaks the kernel, so we
# need to disable it here generally.
kernel_cc_options(-fno-merge-all-constants)

# for gcc -fno-merge-all-constants disables everything, but it is fine
# to have actual conforming behavior enabled.
kernel_cc_options(-fmerge-constants)

# Make sure -fstack-check isn't enabled (like gentoo apparently did)
kernel_cc_options(-fno-stack-check)

# conserve stack if available
kernel_cc_options(-fconserve-stack)

# Require designated initializers for all marked structures
kernel_cc_options(-Wdesignated-init)

if(CONFIG_STRIP_ASM_SYMS)
  target_ld_options(kernel_interface INTERFACE -Wl,-X)
endif()

if(CONFIG_LD_ORPHAN_WARN)
  target_ld_options(kernel_interface INTERFACE -Wl,--orphan-handling=warn)
endif()

# @Intent: Obtain compiler specific flags related to assembly
# ToDo: Remember to get feedback from Oticon on this, as they might use the `ASM_BASE_FLAG` since this is done this way.
target_compile_options(kernel_interface INTERFACE $<$<COMPILE_LANGUAGE:ASM>:-fcheck-new>)

kernel_cc_options(-fno-asynchronous-unwind-tables)
kernel_cc_options(-fno-PIE)

kernel_cc_options(-Wno-keyword-macro -Wno-override-init)

# 不要警告 arrary[-1] = '\0';
kernel_cc_options(-Wno-stringop-overflow)
